﻿using System;
using CommonFramework.Serialize.BytesArray;
using NUnit.Framework;
using Net;
using Net.Proto;

namespace NetServerTest
{
    [TestFixture]
    public class TestNetPacketUtil
    {
        private BytesBuffer _recvBuffer;
        private NetPakcetMove _pakcet;
        private byte[] _packetBytes;

        private void AssertSamePacket(NetPakcetMove other)
        {
            Assert.That(other.PacketName,Is.EqualTo(_pakcet.PacketName));
            Assert.That(other.desc, Is.EqualTo(_pakcet.desc));
            Assert.That(other.x, Is.EqualTo(_pakcet.x));
            Assert.That(other.y, Is.EqualTo(_pakcet.y));
            Assert.That(other.z, Is.EqualTo(_pakcet.z));
        }

        [SetUp]
        public void BeforePerTest()
        {
            _recvBuffer = new BytesBuffer();

            _pakcet = new NetPakcetMove()
            {
                desc = "10.1.20.89:2923",
                x = 9231.42131f,
                y = -1231421.1231f,
                z = 129301.1231231f,
            };

            _packetBytes = NetUtil.GetBytesFromPacket(_pakcet).ToBytes();
        }

        #region 测试GetPacketName

        [Test]
        public void TestGetPacketName_OnBaseType_ReturnEmpty()
        {
            string msgName= NetUtil.GetPacketName<NetPacket>();
            Assert.That(string.IsNullOrEmpty(msgName));

            msgName = NetUtil.GetPacketName(typeof(NetPacket));
            Assert.That(string.IsNullOrEmpty(msgName));
        }
        
        [Test]
        public void TestGetPacketName_IsNotSubclass_ReturnEmpty()
        {
            string msgName = NetUtil.GetPacketName(typeof(NetUtil));
            Assert.That(string.IsNullOrEmpty(msgName));
        }

        [Test]
        public void TestGetPacketName_IsMsgBaseSubclass_ReturnSucc()
        {
            string msgName = NetUtil.GetPacketName(typeof(NetPacketPong));
            Assert.That(msgName,Is.EqualTo(typeof(NetPacketPong).FullName));
        }

        #endregion


        #region 测试TryGetPacketFromBytes

        [Test]
        public void TestTryGetPacketFromBytes_OnLenLess2_WillGetFail()
        {
            _recvBuffer.GetWriter().WriteBytes(_packetBytes, 0, 1);
            bool result = NetUtil.TryGetPacketFromBytes(_recvBuffer, out var msg);

            Assert.That(result,Is.False);
            Assert.That(msg,Is.Null);
        }

        [Test]
        public void TestTryPacketMsgFromBytes_OnMsgLenIncomplete_WillGetFail()
        {
            _recvBuffer.GetWriter().WriteBytes(_packetBytes, 0, _packetBytes.Length - 3);
            bool result = NetUtil.TryGetPacketFromBytes(_recvBuffer, out var msg);

            Assert.That(result,Is.False);
            Assert.That(msg,Is.Null);
        }

        [Test]
        public void TestTryGetPacketFromBytes_OnMsgLenComplete_WillGetSucc()
        {
            _recvBuffer.GetWriter().WriteBytes(_packetBytes, 0, _packetBytes.Length);
            bool result = NetUtil.TryGetPacketFromBytes(_recvBuffer, out var msg);

            Assert.That(result,Is.True);
            Assert.That(msg,Is.Not.Null);

            AssertSamePacket(msg as NetPakcetMove);
        }

        [Test]
        public void TestTryGetPacketFromBytes_OnMsgLenOverflow_WillGetSuccAndRemain()
        {
            _recvBuffer.GetWriter().WriteBytes(_packetBytes, 0, _packetBytes.Length);
            //额外多写的数据,在消息包解析出来后应保留未变
            _recvBuffer.GetWriter().WriteBytes(_packetBytes, 0, _packetBytes.Length / 3);

            bool result = NetUtil.TryGetPacketFromBytes(_recvBuffer, out var msg);

            Assert.That(result,Is.True);
            Assert.That(msg,Is.Not.Null);
            AssertSamePacket(msg as NetPakcetMove);

            Assert.That(_recvBuffer.DataLength(), Is.EqualTo(_packetBytes.Length / 3));
        }

        #endregion
    }
}